/* Copyright (c) 2007  Peter Palotas
 *  
 *  This software is provided 'as-is', without any express or implied
 *  warranty. In no event will the authors be held liable for any damages
 *  arising from the use of this software.
 *  
 *  Permission is granted to anyone to use this software for any purpose,
 *  including commercial applications, and to alter it and redistribute it
 *  freely, subject to the following restrictions:
 *  
 *      1. The origin of this software must not be misrepresented; you must not
 *      claim that you wrote the original software. If you use this software
 *      in a product, an acknowledgment in the product documentation would be
 *      appreciated but is not required.
 *  
 *      2. Altered source versions must be plainly marked as such, and must not be
 *      misrepresented as being the original software.
 *  
 *      3. This notice may not be removed or altered from any source
 *      distribution.
 *  
 *  
 *  $Id$
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Plossum.Win32.SystemServices
{
    internal static class UnsafeNativeMethods
    {
        #region Constants

        // Used by DefineDosDevice 
        internal const uint DDD_RAW_TARGET_PATH = 0x00000001;
        internal const uint DDD_REMOVE_DEFINITION = 0x00000002;
        internal const uint DDD_EXACT_MATCH_ON_REMOVE = 0x00000004;
        internal const uint DDD_NO_BROADCAST_SYSTEM = 0x00000008;

        // Used by GetVolumeInformation
        internal const uint FILE_CASE_SENSITIVE_SEARCH = 0x00000001;
        internal const uint FILE_CASE_PRESERVED_NAMES = 0x00000002;
        internal const uint FILE_UNICODE_ON_DISK = 0x00000004;
        internal const uint FILE_PERSISTENT_ACLS = 0x00000008;
        internal const uint FILE_FILE_COMPRESSION = 0x00000010;
        internal const uint FILE_VOLUME_QUOTAS = 0x00000020;
        internal const uint FILE_SUPPORTS_SPARSE_FILES = 0x00000040;
        internal const uint FILE_SUPPORTS_REPARSE_POINTS = 0x00000080;
        internal const uint FILE_SUPPORTS_REMOTE_STORAGE = 0x00000100;
        internal const uint FILE_VOLUME_IS_COMPRESSED = 0x00008000;
        internal const uint FILE_SUPPORTS_OBJECT_IDS = 0x00010000;
        internal const uint FILE_SUPPORTS_ENCRYPTION = 0x00020000;
        internal const uint FILE_NAMED_STREAMS = 0x00040000;
        internal const uint FILE_READ_ONLY_VOLUME = 0x00080000;

        internal const uint DRIVE_UNKNOWN = 0;
        internal const uint DRIVE_NO_ROOT_DIR = 1;
        internal const uint DRIVE_REMOVABLE = 2;
        internal const uint DRIVE_FIXED = 3;
        internal const uint DRIVE_REMOTE = 4;
        internal const uint DRIVE_CDROM = 5;
        internal const uint DRIVE_RAMDISK = 6;

        // Used by various functions dealing with handles
        internal static readonly IntPtr INVALID_HANDLE_VALUE = (IntPtr)(-1);

        // Used by various functions dealing with paths
        public const int MAX_PATH = 261;

        #endregion 


        #region Imported functions

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        internal static extern uint QueryDosDeviceW(string lpDeviceName, StringBuilder lpTargetPath, uint ucchMax);

        [DllImport("kernel32.dll")]
        internal static extern uint GetLogicalDrives();

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool DefineDosDeviceW(uint dwFlags, string lpDeviceName, string lpTargetPath);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetVolumeNameForVolumeMountPointW(string 
            lpszVolumeMountPoint, [Out] StringBuilder lpszVolumeName, uint cchBufferLength);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetVolumePathNameW(string lpszFileName,
            [Out] StringBuilder lpszVolumePathName, uint cchBufferLength);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetVolumePathNamesForVolumeNameW(string lpszVolumeName,
            char[] lpszVolumePathNames, uint cchBuferLength,
            ref uint lpcchReturnLength);


        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool GetVolumeInformationW(
          string RootPathName,
          StringBuilder VolumeNameBuffer,
          int VolumeNameSize,
          out uint VolumeSerialNumber,
          out uint MaximumComponentLength,
          out uint FileSystemFlags,
          StringBuilder FileSystemNameBuffer,
          int nFileSystemNameSize);

        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool SetVolumeLabelW(string lpRootPathName, string lpVolumeName);

        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool SetVolumeMountPointW(string lpszVolumeMountPoint, string lpszVolumeName);

        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool DeleteVolumeMountPointW(string lpszVolumeMountPoint);

        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        internal extern static IntPtr FindFirstVolumeW(StringBuilder lpszVolumeName, int cchBufferLength);

        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool FindNextVolumeW(IntPtr hFindVolume, StringBuilder lpszVolumeName, int cchBufferLength);

        [DllImport("Kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool FindVolumeClose(IntPtr hFindVolume);

        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        internal extern static IntPtr FindFirstVolumeMountPointW(string lpszRootPathName, StringBuilder lpszVolumeMountPoint, int cchBufferLength);

        [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool FindNextVolumeMountPointW(IntPtr hFindVolume, StringBuilder lpszVolumeName, int cchBufferLength);

        [DllImport("Kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool FindVolumeMountPointClose(IntPtr hFindVolume);
        
        [DllImport("Kernel32.dll", SetLastError = true)]
        internal extern static uint GetDriveType(string lpRootPathName);

        [DllImport("Kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal extern static bool GetVolumeInformationByHandleW(IntPtr hFile,
          StringBuilder VolumeNameBuffer,
          int VolumeNameSize,
          out uint VolumeSerialNumber,
          out uint MaximumComponentLength,
          out uint FileSystemFlags,
          StringBuilder FileSystemNameBuffer,
          int nFileSystemNameSize);
      #endregion

    }
}
